package com.topscomm.mis.cbb.file.compare.word.service;

import com.topscomm.basic.exception.ServiceException;
import com.topscomm.mis.cbb.file.compare.word.XWPFWordCommentsDocument;
import lombok.Data;
import lombok.Setter;
import org.apache.poi.ooxml.POIXMLDocumentPart;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.PackagePartName;
import org.apache.poi.openxml4j.opc.PackagingURIHelper;
import org.apache.poi.xwpf.usermodel.*;
import org.apache.xmlbeans.XmlCursor;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTComment;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTComments;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTMarkupRange;

import java.math.BigInteger;
import java.util.Date;

/**
 * @description: POI插入批注的服务类
 * @author: zhanglongfei
 * @date: 2023/2/20 19:45
 */
public class PoiCommentService {

    private XWPFWordCommentsDocument myXWPFCommentsDocument = null;
    private XWPFDocument document = null;
    private BigInteger cId = BigInteger.ZERO;
    @Setter
    private String author = "AI智能";
    @Setter
    private String initials = "IT";

    public PoiCommentService(XWPFDocument document) {
        this.document = document;
        this.createCommentsDocument();
        refreshMaxCommentId(myXWPFCommentsDocument.getComments());
    }

    /**
     * @param table:
     * @param text:
     * @description: 给行加批注
     * @return: void
     * @author: zhanglongfei
     * @date: 2023/2/23 18:16
     * @modify:
     */
    public void insertCommentToTable(XWPFTable table, String text) {
        if (table == null) return;
        try {
            CTComments comments = myXWPFCommentsDocument.getComments();
            comments.getCommentList();
            CTComment ctComment;
            BigInteger cId = this.getCommentId();
            ctComment = comments.addNewComment();
            ctComment.setAuthor(author);
            ctComment.setInitials(initials);
            ctComment.addNewP().addNewR().addNewT().setStringValue(text);
            ctComment.setId(cId);
            table.getCTTbl().addNewCommentRangeStart().setId(cId);
            table.getCTTbl().addNewCommentRangeEnd().setId(cId);
            table.getCTTbl().addNewTr().addNewTc().addNewP().addNewR().addNewCommentReference().setId(cId);
        } catch (Exception ex) {
            System.out.println(ex);
            throw new ServiceException(ex);
        }
    }

    /**
     * @param row:
     * @param text:
     * @description: 给行加批注
     * @return: void
     * @author: zhanglongfei
     * @date: 2023/2/23 18:16
     * @modify:
     */
    public void insertCommentToRow(XWPFTableRow row, String text) {
        if (row == null) return;
        try {
            CTComments comments = myXWPFCommentsDocument.getComments();
            comments.getCommentList();
            CTComment ctComment;
            BigInteger cId = this.getCommentId();
            ctComment = comments.addNewComment();
            ctComment.setAuthor(author);
            ctComment.setInitials(initials);
            ctComment.addNewP().addNewR().addNewT().setStringValue(text);
            ctComment.setId(cId);
            row.getCtRow().addNewCommentRangeStart().setId(cId);
            row.getCtRow().addNewCommentRangeEnd().setId(cId);
            row.getCtRow().addNewTc().addNewP().addNewR().addNewCommentReference().setId(cId);
        } catch (Exception ex) {
            throw new ServiceException(ex);
        }
    }

    /**
     * @param cell:
     * @param text:
     * @description: 给单元格加批注
     * @return: void
     * @author: zhanglongfei
     * @date: 2023/2/23 18:16
     * @modify:
     */
    public void insertCommentToCell(XWPFTableCell cell, String text) {
        if (cell == null) return;
        try {
            CTComments comments = myXWPFCommentsDocument.getComments();
            comments.getCommentList();
            CTComment ctComment;
            BigInteger cId = this.getCommentId();
            ctComment = comments.addNewComment();
            ctComment.setAuthor(author);
            ctComment.setInitials(initials);
            ctComment.addNewP().addNewR().addNewT().setStringValue(text);
            ctComment.setId(cId);
            cell.getCTTc().addNewCommentRangeStart().setId(cId);
            cell.getCTTc().addNewCommentRangeEnd().setId(cId);
            cell.getCTTc().addNewP().addNewR().addNewCommentReference().setId(cId);
        } catch (Exception ex) {
            throw new ServiceException(ex);
        }
    }

    /**
     * @param paragraph:
     * @param text:
     * @description: 给段落加批注
     * @return: void
     * @author: zhanglongfei
     * @date: 2023/2/23 18:11
     * @modify:
     */
    public void insertCommentToParagraph(XWPFParagraph paragraph, String text) {
        if (paragraph == null) return;
        try {
            CTComments comments = myXWPFCommentsDocument.getComments();
            comments.getCommentList();
            CTComment ctComment;
            BigInteger cId = this.getCommentId();
            ctComment = comments.addNewComment();
            ctComment.setAuthor(author);
            ctComment.setInitials(initials);
            ctComment.addNewP().addNewR().addNewT().setStringValue(text);
            ctComment.setId(cId);
            paragraph.getCTP().addNewCommentRangeStart().setId(cId);
            paragraph.getCTP().addNewCommentRangeEnd().setId(cId);
            paragraph.getCTP().addNewR().addNewCommentReference().setId(cId);
        } catch (Exception ex) {
            throw new ServiceException(ex);
        }
    }

    /**
     * @param run:
     * @param text:
     * @description: 给Run加批注
     * @return: void
     * @author: zhanglongfei
     * @date: 2023/2/23 18:11
     * @modify:
     */
    public void insertCommentToRun(XWPFRun run, String text) {
        if (run == null) return;
        try {
            CTComments comments = myXWPFCommentsDocument.getComments();
            comments.getCommentList();
            CTComment ctComment;
            BigInteger cId = this.getCommentId();
            ctComment = comments.addNewComment();
            ctComment.setAuthor(author);
            ctComment.setInitials(initials);
            ctComment.addNewP().addNewR().addNewT().setStringValue(text);
            ctComment.setId(cId);
            run.getCTR().addNewCommentReference().setId(cId);
        } catch (Exception ex) {
            throw new ServiceException(ex);
        }
    }

    /**
     * @description: 建立Word中的批注文档
     * @return: com.topscomm.mis.cbb.file.compare.word.XWPFWordCommentsDocument
     * @author: zhanglongfei
     * @date: 2023/2/20 19:51
     * @modify:
     */
    private void createCommentsDocument() {
        try {
            for (POIXMLDocumentPart.RelationPart rpart : document.getRelationParts()) {
                String relation = rpart.getRelationship().getRelationshipType();
                if (relation.equals(XWPFRelation.COMMENT.getRelation())) {
                    POIXMLDocumentPart part = rpart.getDocumentPart();
                    myXWPFCommentsDocument = new XWPFWordCommentsDocument(part.getPackagePart());
                    String rId = document.getRelationId(part);
                    document.addRelation(rId, XWPFRelation.COMMENT, myXWPFCommentsDocument);
                }
            }
            if (myXWPFCommentsDocument == null) {
                OPCPackage oPCPackage = document.getPackage();
                PackagePartName partName = PackagingURIHelper.createPartName("/word/comments.xml");
                PackagePart part = oPCPackage.createPart(
                        partName,
                        "application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml");
                myXWPFCommentsDocument = new XWPFWordCommentsDocument(part);
                document.addRelation(null, XWPFRelation.COMMENT, myXWPFCommentsDocument);
            }
        } catch (Exception ex) {
            throw new ServiceException(ex);
        }
    }

    /**
     * @description: 刷新最大CommentId
     * @return: void
     * @author: zhanglongfei
     * @date: 2023/2/21 15:09
     * @modify:
     */
    private BigInteger getCommentId() {
        cId = cId.add(BigInteger.ONE);
        return cId;
    }

    /**
     * @description: 刷新最大id
     * @return: void
     * @author: zhanglongfei
     * @date: 2023/2/21 19:20
     * @modify:
     */
    private void refreshMaxCommentId(CTComments comments) {
        for (CTComment ctComment : comments.getCommentList()) {
            if (ctComment.getId().compareTo(cId) == 1) {
                cId = ctComment.getId();
            }
        }
        cId = cId.add(BigInteger.ONE);
    }
}
